
#include "MainYour.h"
#define TAG			"KeyIrHal"

static void panelKeyScan(KEY_RAM* key){						// 面板按键扫描
	// 面板按键扫描行输出，现在的代码设计最大为8，超过要修改代码
	uint8_t bits = (1 << key->PsLine);						// 扫描行转换为位
//CLOGD(TAG, "key->PsValue A %d %02x",key->PsLine, (1 << bits));			
	for (char position = 0; position < PANEL_KEY_LINE; position++){
		char level = ((1 << position) & bits) ? 1 : 0;			// 当前的行为高，不是当前的行为低
		HAL_KEY_PS_OUT(position, level ^ 1);				// 当前的行输出低电平
//CLOGD(TAG, "key->PsValue B %d %d %d %02x", position,level,key->PsLine,(1 << position));			
	}
	// 面板按键扫描列输入，现在的代码设计最大为5，超过要修改代码
	uint8_t value = 0;
	for (char position = 0; position < PANEL_KEY_COLUMN; position++){
		if (HAL_KEY_PS_IN(position) == 0){					// 列输入，如果对应的按键按下为低电平
			value |= 1 << position;		
		}			
	}
    if (value){												// 面板按键
//CLOGD(TAG, "key->PsValue B %02x %d", value,key->PsLine);		
        value = (value << 3) | (key->PsLine % PANEL_KEY_LINE);  // B2:B0为行(最大为8行) B7:B3为列(最大为5列)  
        if (key->PsCode == value){							// 按键
            if (++key->PsConfirmTm > 8){ 					// 面板按键的确认时间
		        if (!key->PsStepMode){						// 0=长按模式 1=设置为按键松手才继续检测
	                key->PsDone = 1;						// 面板按键 检测成功
				//	CLOGD(TAG, "PsDone Code:%02x", key->PsCode);						
	            }
				key->PsConfirmTm = 0;						// 面板按键的确认时间
            }
        }else {
			key->PsStepMode = 0; 
			key->PsConfirmTm = 0; 							// 面板按键的确认时间
			key->PsCode = value;
		}
    }else{ 
        if (++key->PsLine >= PANEL_KEY_LINE){ 
            key->PsLine = 0;  
        }           
		key->PsStepMode = 0; 
		key->PsConfirmTm = 0; 								// 面板按键的确认时间
    }
    return;
}
#if (KEY_JOG_MODE != 0)										// 旋转按钮模式，0为不支持 1为正向，2为反向	
static void checkJop(KEY_RAM* key){							// 旋转按钮 旋转
    if (!key->JopInputEnl){
        if (HAL_KEY_JOP_IN(0) && HAL_KEY_JOP_IN(1) && (++key->JopInputTm > 3)){
            key->JopInputTm = 0; 
            key->JopInputEnl = 1;
        }
        key->JopSta00 = 0;
        key->JopSta01 = 0;
    }                 
    else if (HAL_KEY_JOP_IN(0) != HAL_KEY_JOP_IN(1)){
        if (key->JopInputEnl){
            key->JogCode = HAL_KEY_JOP_IN(1);
            if ((key->JogCode == key->JogSave) || (key->JopLockTm == 0)){
                key->JogDone = 1;
//CLOGD(TAG, "Jop Done %d",key->JogCode);				
            }
            key->JogSave = key->JogCode;
            key->JopLockTm = 3;
            key->JopInputTm = 0;
            key->JopInputEnl = 0;
            key->JopSta01 = 0;
        }
        else {
            if (key->JopSta01){
                key->JopLockTm = 3;
                key->JopInputTm = 0;                          
                key->JopInputEnl = 0;
            }
            key->JopSta01 = 1;
        }                                
        key->JopSta00 = 0;
    }
    else if (!HAL_KEY_JOP_IN(0) && !HAL_KEY_JOP_IN(1)){ 
        if (key->JopSta00){
            key->JopLockTm = 3;
            key->JopInputTm = 0; 
            key->JopInputEnl = 0;
        }
        key->JopSta00 = 1;
        key->JopSta01 = 0;
    }
    return;
}	
#endif		// #if (KEY_JOG_MODE != 0)	 旋转按钮模式，0为不支持 1为正向，2为反向	
//	CLOGD(TAG, "Ir A %d %d",MSYS_GET_TICK_10US(), key->gRmStatus);		
// MSYS_PIN_TEST0(2);										// 测试脚取反
void MKEY_HalIrFalling(){									// 红外遥控接收输出的下降边缘触发进入中断
	KEY_RAM* key = &mKEY;									// 全局变量转局部变量
	if (!key->IrError){
		uint16_t tick16 = MSYS_GET_TICK_10US();
		if (++key->IrStatus == 1){
			key->IrTick16 = tick16;
		}else {
			int tick = (tick16 > key->IrTick16) ? tick16 - key->IrTick16 : ((tick16 + 0x10000) - key->IrTick16);
			key->IrTick16 = MSYS_GET_TICK_10US();
			if (key->IrStatus == 2){    
				//CLOGD(TAG, "KEY.Ir B %d",tick);		
				if (tick < 1000 || tick > 1450){			// 9ms + 4.5ms || 9ms + 2ms
					key->IrError = 1; 
					//CLOGD(TAG, "KEY.Ir Error tick:%d", tick);
				}
			}else {
				// CLOGD(TAG, "KEY.Ir C %d %d %04x",tick,key->IrStatus, key->IrTick16);
				key->IrBuffer <<= 1;
				if (tick > 160){							// 110us 或者 220us 
					key->IrBuffer |= 0x00000001;  				
				}
				if (key->IrStatus == 2+32){ 
					if ((key->IrBuffer & 0xffff0000) == KEY_IR_CUSTOM){
						uint8_t code1 = (key->IrBuffer >> 8) & 0xff;
						uint8_t code2 = key->IrBuffer & 0xff;
						//CLOGD(TAG, "code1= %02x code2=%02x %02x", code1, code2, code2 ^ 0xff);	
						if (code1 == (code2 ^ 0xff)){
						//	CLOGD(TAG, "KEY.Ir OK %08x", key->IrBuffer&0xffff);	
							key->IrCode = code1;
							key->IrDone = 1;							
						}else{
							CLOGD(TAG, "KEY.Ir Error %02x %02x(%04x %04x)", code1, code2, key->IrTick16, MSYS_GET_TICK_10US());
							key->IrError = 1; 
						}
					}else{
						key->IrError = 1; 
						CLOGE(TAG, "KEY.Ir Error %08x(%04x %04x)", key->IrBuffer, key->IrTick16, MSYS_GET_TICK_10US());
					}					
				}
			}
        }
    }
    key->IrTimeout = 1; 
}
void MKEY_HalTime1ms(){										// 1ms
	KEY_RAM* key = &mKEY;									// 全局变量转局部变量
#if (KEY_JOG_MODE != 0)										// 旋转按钮模式，0为不支持 1为正向，2为反向	
	checkJop(key);											// 旋转按钮
#endif	
	if (++key->Ps10ms >= 10){
		key->Ps10ms = 0;
		panelKeyScan(key);									// 面板按键扫描
	}
	if (key->IrTimeout != 0 && ++key->IrTimeout > 159/10){		// 16ms
		if(!key->IrError && (key->IrStatus == 2) && (key->IrContinCanclTm != 0)){
            if (key->IrContinSpeed < 8){
				if ((key->IrContinSpeed & 3) == 3){
					key->IrDone = 1;
					CLOGD(TAG, "IrDone B");
				}
				++key->IrContinSpeed;
			}
			else {
				key->IrDone = 1;
				CLOGD(TAG, "IrDone C");
			}
        } 
		key->IrStatus = 0;
		key->IrError = 0; 
		key->IrTimeout = 0;
    }	
}			
void MKEY_HalInit(){
}

